package com.micro.ai.auth.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.micro.ai.auth.dto.RoleCreateRequest;
import com.micro.ai.auth.dto.RoleDTO;
import com.micro.ai.auth.dto.RoleUpdateRequest;
import com.micro.ai.auth.service.RoleService;
import com.micro.ai.commons.domain.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.micro.ai.auth.annotation.AuditLogAnnotation;
import java.util.List;

/**
 * 角色管理控制器
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@RestController
@RequestMapping("/api/roles")
@Tag(name = "角色管理", description = "角色的增删改查、权限分配等操作")
public class RoleController {

    @Autowired
    private RoleService roleService;

    /**
     * 创建角色
     */
    @PostMapping
    @PreAuthorize("hasAuthority('role:create')")
    @Operation(summary = "创建角色", description = "创建新的角色")
    @AuditLogAnnotation(action = "CREATE", resourceType = "ROLE", description = "创建角色")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
            content = @Content(schema = @Schema(implementation = RoleDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误或角色编码已存在"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<RoleDTO> createRole(@Valid @RequestBody RoleCreateRequest request) {
        log.info("创建角色: code={}, name={}", request.getCode(), request.getName());
        RoleDTO role = roleService.createRole(request);
        return ApiResponse.success(role);
    }

    /**
     * 更新角色
     */
    @PutMapping("/{roleId}")
    @PreAuthorize("hasAuthority('role:update')")
    @Operation(summary = "更新角色", description = "更新指定角色的信息")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "ROLE", description = "更新角色")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
            content = @Content(schema = @Schema(implementation = RoleDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<RoleDTO> updateRole(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId,
            @Valid @RequestBody RoleUpdateRequest request) {
        log.info("更新角色: roleId={}", roleId);
        RoleDTO role = roleService.updateRole(roleId, request);
        return ApiResponse.success(role);
    }

    /**
     * 删除角色
     */
    @DeleteMapping("/{roleId}")
    @PreAuthorize("hasAuthority('role:delete')")
    @Operation(summary = "删除角色", description = "删除指定角色")
    @AuditLogAnnotation(action = "DELETE", resourceType = "ROLE", description = "删除角色")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "角色正在使用中不能删除"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<Void> deleteRole(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId) {
        log.info("删除角色: roleId={}", roleId);
        roleService.deleteRole(roleId);
        return ApiResponse.success();
    }

    /**
     * 获取角色详情
     */
    @GetMapping("/{roleId}")
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "获取角色详情", description = "根据角色ID获取角色详细信息")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
            content = @Content(schema = @Schema(implementation = RoleDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<RoleDTO> getRoleById(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId) {
        RoleDTO role = roleService.getRoleById(roleId);
        return ApiResponse.success(role);
    }

    /**
     * 根据编码获取角色
     */
    @GetMapping("/code/{code}")
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "根据编码获取角色", description = "根据角色编码获取角色信息")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
            content = @Content(schema = @Schema(implementation = RoleDTO.class))),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<RoleDTO> getRoleByCode(
            @Parameter(description = "角色编码", required = true, example = "ROLE_ADMIN") @PathVariable String code) {
        RoleDTO role = roleService.getRoleByCode(code);
        return ApiResponse.success(role);
    }

    /**
     * 分页查询角色
     */
    @GetMapping
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "分页查询角色", description = "根据条件分页查询角色列表")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<Page<RoleDTO>> listRoles(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") int pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") int pageSize,
            @Parameter(description = "租户ID") @RequestParam(required = false) String tenantId,
            @Parameter(description = "关键词（名称/编码/描述）") @RequestParam(required = false) String keyword,
            @Parameter(description = "状态") @RequestParam(required = false) String status) {
        Page<RoleDTO> page = roleService.listRoles(pageNum, pageSize, tenantId, keyword, status);
        return ApiResponse.success(page);
    }

    /**
     * 获取所有角色（不分页）
     */
    @GetMapping("/all")
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "获取所有角色", description = "获取所有活跃角色列表（不分页）")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限")
    })
    public ApiResponse<List<RoleDTO>> getAllRoles(
            @Parameter(description = "租户ID") @RequestParam(required = false) String tenantId) {
        List<RoleDTO> roles = roleService.getAllRoles(tenantId);
        return ApiResponse.success(roles);
    }

    /**
     * 为角色分配权限
     */
    @PostMapping("/{roleId}/permissions")
    @PreAuthorize("hasAuthority('role:assign-permission')")
    @Operation(summary = "分配权限", description = "为角色分配一组权限（覆盖原有权限）")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "ROLE", description = "分配角色权限")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "分配成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色或权限不存在")
    })
    public ApiResponse<Void> assignPermissions(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId,
            @Parameter(description = "权限ID列表", required = true) @RequestBody List<String> permissionIds) {
        log.info("为角色分配权限: roleId={}, permissionIds={}", roleId, permissionIds);
        roleService.assignPermissions(roleId, permissionIds);
        return ApiResponse.success();
    }

    /**
     * 移除角色的权限
     */
    @DeleteMapping("/{roleId}/permissions")
    @PreAuthorize("hasAuthority('role:remove-permission')")
    @Operation(summary = "移除权限", description = "移除角色的指定权限")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "ROLE", description = "移除角色权限")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "移除成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<Void> removePermissions(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId,
            @Parameter(description = "权限ID列表", required = true) @RequestBody List<String> permissionIds) {
        log.info("移除角色权限: roleId={}, permissionIds={}", roleId, permissionIds);
        roleService.removePermissions(roleId, permissionIds);
        return ApiResponse.success();
    }

    /**
     * 获取角色的所有权限（已废弃）
     * 
     * @deprecated 新权限系统不再使用独立的 permissions 表，请使用 GET /{roleId}/menus 获取角色的菜单权限
     */
    @Deprecated
    @GetMapping("/{roleId}/permissions")
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "获取角色权限（已废弃）", description = "此接口已废弃，请使用 GET /{roleId}/menus")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<List<String>> getRolePermissions(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId) {
        List<String> permissions = roleService.getRolePermissions(roleId);
        return ApiResponse.success(permissions);
    }

    /**
     * 获取用户的所有角色
     */
    @GetMapping("/user/{userId}")
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "获取用户角色", description = "获取用户拥有的所有角色")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "用户不存在")
    })
    public ApiResponse<List<RoleDTO>> getUserRoles(
            @Parameter(description = "用户ID", required = true) @PathVariable String userId) {
        List<RoleDTO> roles = roleService.getUserRoles(userId);
        return ApiResponse.success(roles);
    }
    
    /**
     * 为角色分配菜单权限
     */
    @PostMapping("/{roleId}/menus")
    @PreAuthorize("hasAuthority('role:assign-permission')")
    @Operation(summary = "分配菜单权限", description = "为角色分配菜单权限（包括按钮权限）")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "ROLE", description = "分配角色菜单权限")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "分配成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<Void> assignMenus(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId,
            @Parameter(description = "菜单ID列表", required = true) @RequestBody List<String> menuIds) {
        log.info("为角色分配菜单权限: roleId={}, menuIds={}", roleId, menuIds);
        roleService.assignMenus(roleId, menuIds);
        return ApiResponse.success();
    }
    
    /**
     * 移除角色的菜单权限
     */
    @DeleteMapping("/{roleId}/menus")
    @PreAuthorize("hasAuthority('role:remove-permission')")
    @Operation(summary = "移除菜单权限", description = "移除角色的指定菜单权限")
    @AuditLogAnnotation(action = "UPDATE", resourceType = "ROLE", description = "移除角色菜单权限")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "移除成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<Void> removeMenus(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId,
            @Parameter(description = "菜单ID列表", required = true) @RequestBody List<String> menuIds) {
        log.info("移除角色菜单权限: roleId={}, menuIds={}", roleId, menuIds);
        roleService.removeMenus(roleId, menuIds);
        return ApiResponse.success();
    }
    
    /**
     * 获取角色的菜单权限
     */
    @GetMapping("/{roleId}/menus")
    @PreAuthorize("hasAuthority('role:view')")
    @Operation(summary = "获取角色菜单", description = "获取角色拥有的所有菜单ID")
    @ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "401", description = "未授权"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "403", description = "无权限"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "角色不存在")
    })
    public ApiResponse<List<String>> getRoleMenus(
            @Parameter(description = "角色ID", required = true) @PathVariable String roleId) {
        List<String> menuIds = roleService.getRoleMenuIds(roleId);
        return ApiResponse.success(menuIds);
    }
}

